From 18a23ebe612bc869eda0eff1a2634b348b0f3226 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Mon, 14 Aug 2006 13:20:40 -0600 Subject: [PATCH] [IA64] convert stats to perfc, get rid of unsafe hypercall Convert remaining stat counter to perfc. Get rid of unsafe hypercall. Signed-off-by: Tristan Gingold --- xen/arch/ia64/xen/domain.c | 1 - xen/arch/ia64/xen/faults.c | 1 - xen/arch/ia64/xen/hypercall.c | 32 -------- xen/arch/ia64/xen/privop.c | 1 - xen/arch/ia64/xen/privop_stat.c | 113 +++++++++++++++-------------- xen/arch/ia64/xen/vcpu.c | 4 +- xen/arch/ia64/xen/vhpt.c | 12 ++- xen/include/asm-ia64/config.h | 6 ++ xen/include/asm-ia64/perfc.h | 12 ++- xen/include/asm-ia64/perfc_defn.h | 17 +++++ xen/include/asm-ia64/privop_stat.h | 44 ++++++++--- xen/include/asm-ia64/vhpt.h | 2 +- 12 files changed, 131 insertions(+), 114 deletions(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 86ff7d85f5..5258c40f95 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -47,7 +47,6 @@ #include #include #include -#include unsigned long dom0_size = 512*1024*1024; unsigned long dom0_align = 64*1024*1024; diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index a37dfc8c80..16bef26b31 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index 97924b8776..6fcc1ef72e 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -28,7 +28,6 @@ #include #include #include -#include static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop); static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg); @@ -275,11 +274,6 @@ fw_hypercall (struct pt_regs *regs) return IA64_NO_FAULT; } -/* opt_unsafe_hypercall: If true, unsafe debugging hypercalls are allowed. - These can create security hole. */ -static int opt_unsafe_hypercall = 0; -boolean_param("unsafe_hypercall", opt_unsafe_hypercall); - IA64FAULT ia64_hypercall (struct pt_regs *regs) { @@ -287,32 +281,6 @@ ia64_hypercall (struct pt_regs *regs) unsigned long index = regs->r2; int privlvl = (regs->cr_ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT; - if (index >= FW_HYPERCALL_FIRST_USER) { - /* Note: user hypercalls are not safe, since Xen doesn't - check memory access privilege: Xen does not deny reading - or writing to kernel memory. */ - if (!opt_unsafe_hypercall) { - printf("user xen/ia64 hypercalls disabled\n"); - regs->r8 = -1; - } - else switch (index) { - case 0xffff: - regs->r8 = dump_privop_counts_to_user( - (char *) vcpu_get_gr(v,32), - (int) vcpu_get_gr(v,33)); - break; - case 0xfffe: - regs->r8 = zero_privop_counts_to_user( - (char *) vcpu_get_gr(v,32), - (int) vcpu_get_gr(v,33)); - break; - default: - printf("unknown user xen/ia64 hypercall %lx\n", index); - regs->r8 = do_ni_hypercall(); - } - return IA64_NO_FAULT; - } - /* Hypercalls are only allowed by kernel. Kernel checks memory accesses. */ if (VMX_DOMAIN(v) ? (privlvl != 0) : (privlvl != 2)) { diff --git a/xen/arch/ia64/xen/privop.c b/xen/arch/ia64/xen/privop.c index 0172dd87c3..2053317e51 100644 --- a/xen/arch/ia64/xen/privop.c +++ b/xen/arch/ia64/xen/privop.c @@ -13,7 +13,6 @@ #include #include #include -#include long priv_verbose=0; unsigned long privop_trace = 0; diff --git a/xen/arch/ia64/xen/privop_stat.c b/xen/arch/ia64/xen/privop_stat.c index 466b5b1ffd..5bdd5adc6a 100644 --- a/xen/arch/ia64/xen/privop_stat.c +++ b/xen/arch/ia64/xen/privop_stat.c @@ -1,26 +1,55 @@ -#include -#include #include -#include +#include +#include +#include +#include -#ifdef PRIVOP_ADDR_COUNT -#define PRIVOP_COUNT_NINSTS 2 -#define PRIVOP_COUNT_NADDRS 30 +#ifdef CONFIG_PRIVOP_ADDRS struct privop_addr_count { - const char *instname; unsigned long addr[PRIVOP_COUNT_NADDRS]; - unsigned long count[PRIVOP_COUNT_NADDRS]; - unsigned long overflow; + unsigned int count[PRIVOP_COUNT_NADDRS]; + unsigned int overflow; + atomic_t *perfc_addr; + atomic_t *perfc_count; + atomic_t *perfc_overflow; }; +#undef PERFCOUNTER +#define PERFCOUNTER(var, name) + +#undef PERFCOUNTER_CPU +#define PERFCOUNTER_CPU(var, name) + +#undef PERFCOUNTER_ARRAY +#define PERFCOUNTER_ARRAY(var, name, size) + +#undef PERFSTATUS +#define PERFSTATUS(var, name) + +#undef PERFSTATUS_CPU +#define PERFSTATUS_CPU(var, name) + +#undef PERFSTATUS_ARRAY +#define PERFSTATUS_ARRAY(var, name, size) -static struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = { - [_GET_IFA] = { "=ifa", { 0 }, { 0 }, 0 }, - [_THASH] = { "thash", { 0 }, { 0 }, 0 } +#undef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) \ + { \ + { 0 }, { 0 }, 0, \ + perfcounters.privop_addr_##name##_addr, \ + perfcounters.privop_addr_##name##_count, \ + perfcounters.privop_addr_##name##_overflow \ + }, + +static struct privop_addr_count privop_addr_counter[] = { +#include }; -void privop_count_addr(unsigned long iip, int inst) +#define PRIVOP_COUNT_NINSTS \ + (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0])) + +void privop_count_addr(unsigned long iip, enum privop_inst inst) { struct privop_addr_count *v = &privop_addr_counter[inst]; int i; @@ -41,29 +70,28 @@ void privop_count_addr(unsigned long iip, int inst) v->overflow++;; } -static int dump_privop_addrs(char *buf) +void gather_privop_addrs(void) { int i, j; - char *s = buf; - s += sprintf(s, "Privop addresses:\n"); + atomic_t *v; for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { - struct privop_addr_count *v = &privop_addr_counter[i]; - s += sprintf(s, "%s:\n", v->instname); - for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) { - if (!v->addr[j]) - break; - s += sprintf(s, " at 0x%lx #%ld\n", - v->addr[j], v->count[j]); - } - if (v->overflow) - s += sprintf(s, " other #%ld\n", v->overflow); + /* Note: addresses are truncated! */ + v = privop_addr_counter[i].perfc_addr; + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) + atomic_set(&v[j], privop_addr_counter[i].addr[j]); + + v = privop_addr_counter[i].perfc_count; + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) + atomic_set(&v[j], privop_addr_counter[i].count[j]); + + atomic_set(privop_addr_counter[i].perfc_overflow, + privop_addr_counter[i].overflow); } - return s - buf; } -static void zero_privop_addrs(void) +void reset_privop_addrs(void) { - int i,j; + int i, j; for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { struct privop_addr_count *v = &privop_addr_counter[i]; for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) @@ -119,30 +147,3 @@ static const char * const hyperpriv_str[HYPERPRIVOP_MAX+1] = { "=rr", "rr=", "kr=", "fc", "=cpuid", "=pmd", "=ar.eflg", "ar.eflg=" }; #endif - -#define TMPBUFLEN 8*1024 -int dump_privop_counts_to_user(char __user *ubuf, int len) -{ - char buf[TMPBUFLEN]; - int n; - - if (len < TMPBUFLEN) - return -1; - - n = 0; -#ifdef PRIVOP_ADDR_COUNT - n += dump_privop_addrs(buf + n); -#endif - n += dump_vhpt_stats(buf + n); - if (__copy_to_user(ubuf,buf,n)) - return -1; - return n; -} - -int zero_privop_counts_to_user(char __user *ubuf, int len) -{ -#ifdef PRIVOP_ADDR_COUNT - zero_privop_addrs(); -#endif - return 0; -} diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 18fd1989b8..acbc492686 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -473,7 +473,7 @@ IA64FAULT vcpu_get_iip(VCPU *vcpu, UINT64 *pval) IA64FAULT vcpu_get_ifa(VCPU *vcpu, UINT64 *pval) { - PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_GET_IFA); + PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_get_ifa); *pval = PSCB(vcpu,ifa); return (IA64_NO_FAULT); } @@ -540,7 +540,7 @@ IA64FAULT vcpu_get_iim(VCPU *vcpu, UINT64 *pval) IA64FAULT vcpu_get_iha(VCPU *vcpu, UINT64 *pval) { - PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_THASH); + PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_thash); *pval = PSCB(vcpu,iha); return (IA64_NO_FAULT); } diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 9789c0010a..7df751c2c7 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -261,13 +261,12 @@ void flush_tlb_mask(cpumask_t mask) (cpu, (void (*)(void *))flush_tlb_vhpt_all, NULL, 1, 1); } -int dump_vhpt_stats(char *buf) +#ifdef PERF_COUNTERS +void gather_vhpt_stats(void) { int i, cpu; - char *s = buf; - s += sprintf(s,"VHPT usage (%ld entries):\n", - (unsigned long) VHPT_NUM_ENTRIES); + perfc_set(vhpt_nbr_entries, VHPT_NUM_ENTRIES); for_each_present_cpu (cpu) { struct vhpt_lf_entry *v = __va(per_cpu(vhpt_paddr, cpu)); @@ -276,8 +275,7 @@ int dump_vhpt_stats(char *buf) for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) if (!(v->ti_tag & INVALID_TI_TAG)) vhpt_valid++; - s += sprintf(s," cpu %d: %ld\n", cpu, vhpt_valid); + perfc_seta(vhpt_valid_entries, cpu, vhpt_valid); } - - return s - buf; } +#endif diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index 12d48f7baf..e1a4962074 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -37,6 +37,12 @@ #define MAX_DMADOM_PFN (0x7FFFFFFFUL >> PAGE_SHIFT) /* 31 addressable bits */ +/* If PERFC is used, include privop maps. */ +#ifdef PERF_COUNTERS +#define CONFIG_PRIVOP_ADDRS +#define PRIVOP_COUNT_NADDRS 30 +#endif + #ifndef __ASSEMBLY__ // can't find where this typedef was before?!? diff --git a/xen/include/asm-ia64/perfc.h b/xen/include/asm-ia64/perfc.h index 37a0ac3bc5..0ca2189622 100644 --- a/xen/include/asm-ia64/perfc.h +++ b/xen/include/asm-ia64/perfc.h @@ -1,16 +1,22 @@ #ifndef __ASM_PERFC_H__ #define __ASM_PERFC_H__ -static inline void arch_perfc_printall (void) +#include +#include + +static inline void arch_perfc_printall(void) { } -static inline void arch_perfc_reset (void) +static inline void arch_perfc_reset(void) { + reset_privop_addrs(); } -static inline void arch_perfc_gather (void) +static inline void arch_perfc_gather(void) { + gather_vhpt_stats(); + gather_privop_addrs(); } #endif diff --git a/xen/include/asm-ia64/perfc_defn.h b/xen/include/asm-ia64/perfc_defn.h index f09e90d03a..d3776611ff 100644 --- a/xen/include/asm-ia64/perfc_defn.h +++ b/xen/include/asm-ia64/perfc_defn.h @@ -40,3 +40,20 @@ PERFCOUNTER_ARRAY(fast_hyperprivop, "fast hyperprivops", HYPERPRIVOP_MAX + 1) PERFCOUNTER_ARRAY(slow_reflect, "slow reflection", 0x80) PERFCOUNTER_ARRAY(fast_reflect, "fast reflection", 0x80) + +PERFSTATUS(vhpt_nbr_entries, "nbr of entries per VHPT") +PERFSTATUS_CPU(vhpt_valid_entries, "nbr of valid entries in VHPT") + +#ifdef CONFIG_PRIVOP_ADDRS +#ifndef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) \ +PERFSTATUS_ARRAY(privop_addr_##name##_addr, "privop-addrs addr " #name, \ + PRIVOP_COUNT_NADDRS) \ +PERFSTATUS_ARRAY(privop_addr_##name##_count, "privop-addrs count " #name, \ + PRIVOP_COUNT_NADDRS) \ +PERFSTATUS(privop_addr_##name##_overflow, "privop-addrs overflow " #name) +#endif + +PERFPRIVOPADDR(get_ifa) +PERFPRIVOPADDR(thash) +#endif diff --git a/xen/include/asm-ia64/privop_stat.h b/xen/include/asm-ia64/privop_stat.h index b48a39ed3c..a5ea27ad82 100644 --- a/xen/include/asm-ia64/privop_stat.h +++ b/xen/include/asm-ia64/privop_stat.h @@ -1,22 +1,46 @@ #ifndef _XEN_UA64_PRIVOP_STAT_H #define _XEN_UA64_PRIVOP_STAT_H -#include +#include -extern int dump_privop_counts_to_user(char *, int); -extern int zero_privop_counts_to_user(char *, int); +#ifdef CONFIG_PRIVOP_ADDRS -#define PRIVOP_ADDR_COUNT +extern void gather_privop_addrs(void); +extern void reset_privop_addrs(void); -#ifdef PRIVOP_ADDR_COUNT +#undef PERFCOUNTER +#define PERFCOUNTER(var, name) + +#undef PERFCOUNTER_CPU +#define PERFCOUNTER_CPU(var, name) + +#undef PERFCOUNTER_ARRAY +#define PERFCOUNTER_ARRAY(var, name, size) + +#undef PERFSTATUS +#define PERFSTATUS(var, name) + +#undef PERFSTATUS_CPU +#define PERFSTATUS_CPU(var, name) + +#undef PERFSTATUS_ARRAY +#define PERFSTATUS_ARRAY(var, name, size) + +#undef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) privop_inst_##name, + +enum privop_inst { +#include +}; + +#undef PERFPRIVOPADDR -/* INST argument of PRIVOP_COUNT_ADDR. */ -#define _GET_IFA 0 -#define _THASH 1 #define PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst) -extern void privop_count_addr(unsigned long addr, int inst); +extern void privop_count_addr(unsigned long addr, enum privop_inst inst); #else -#define PRIVOP_COUNT_ADDR(x,y) do {} while (0) +#define PRIVOP_COUNT_ADDR(x,y) do {} while (0) +#define gather_privop_addrs() do {} while (0) +#define reset_privop_addrs() do {} while (0) #endif #endif /* _XEN_UA64_PRIVOP_STAT_H */ diff --git a/xen/include/asm-ia64/vhpt.h b/xen/include/asm-ia64/vhpt.h index afd3d7f279..cb4fc30462 100644 --- a/xen/include/asm-ia64/vhpt.h +++ b/xen/include/asm-ia64/vhpt.h @@ -32,7 +32,7 @@ struct vhpt_lf_entry { #define INVALID_TI_TAG 0x8000000000000000L extern void vhpt_init (void); -extern int dump_vhpt_stats(char *buf); +extern void gather_vhpt_stats(void); extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long logps); extern void vhpt_insert (unsigned long vadr, unsigned long pte, -- 2.30.2